{$I fbcc.inc}
unit uExec;

interface

function WinExecAndWait32(Cmd : String; nShowCmd: Integer): integer;

implementation

uses
  Windows,
  Messages,
  FileCtrl,
  SysUtils;

function WinExecAndWait32(Cmd : String; nShowCmd : Integer): Integer;
var
  Msg        : TMsg;
  lpExitCode : Cardinal;
  StartupInfo: TStartupInfo;
  ProcessInfo: TProcessInformation;
  StartDir   : String;
begin
  FillChar(StartupInfo, SizeOf(TStartupInfo), 0);
  with StartupInfo do
  begin
    cb := SizeOf(TStartupInfo);
    dwFlags := STARTF_USESHOWWINDOW or STARTF_FORCEONFEEDBACK;
    wShowWindow := nShowCmd; // Either SW_SHOW or SW_HIDE.
  end;

  StartDir := ExtractFileDir(Cmd);
  if not DirectoryExists(StartDir) then StartDir := '.';
  if CreateProcess(
    nil,
    PChar(Cmd),
    nil,
    nil,
    False,
    NORMAL_PRIORITY_CLASS,
    nil,
    PChar(StartDir),
    StartupInfo,
    ProcessInfo)
  then begin
    repeat
      Sleep(500);
      while PeekMessage(Msg, 0, 0, 0, PM_REMOVE) do begin
        if Msg.Message = WM_QUIT then Halt(Msg.WParam);
        TranslateMessage(Msg);
        DispatchMessage(Msg);
      end;
      GetExitCodeProcess(ProcessInfo.hProcess, lpExitCode);
    until lpExitCode <> Still_Active;

    // Not sure this is necessary but seen in in some code elsewhere.
    with ProcessInfo do
    begin
      CloseHandle(hThread);
      CloseHandle(hProcess);
    end;
    Result := lpExitCode;
  end
  else
    // Error occured during CreateProcess. See help for details.
    Result := -1;
end;

end.
